﻿using Microsoft.AspNetCore.SignalR;
using System.Collections.Concurrent;
using XinLife.Common.SignalR;
using XinLife.Model;

namespace XinLife.Common.Filters
{
    /// <summary>
    /// 后台超时退出
    /// </summary>
    public class TimeoutExitService : IHostedService, IDisposable
    {
        private Timer _timer;
        private readonly ILogger<TimeoutExitService> _logger;
        private readonly IHubContext<ChatHub, IChatClient> _hubContext;
        private CancellationTokenSource _cts;

        public static ConcurrentDictionary<string, DateTime> ConnectionUsers = new ConcurrentDictionary<string, DateTime>();

        public TimeoutExitService(ILogger<TimeoutExitService> logger, IHubContext<ChatHub, IChatClient> hubContext)
        {
            _logger = logger;
            _hubContext = hubContext;
            _cts = new CancellationTokenSource();
        }

        public void DoWork(object obj)
        {
            // 循环读取元素
            foreach (KeyValuePair<string, DateTime> kvp in ConnectionUsers)
            {
                if (DateTime.Now > kvp.Value.AddMinutes(30))
                {
                    var connectionId = ChatHub.Connections.Where(t => t.Value == kvp.Key).Select(t => t.Key).ToList();
                    _hubContext.Clients.Clients(connectionId).TimeOut();
                }
            }
            var cts = obj as CancellationTokenSource;
            if (!cts.Token.IsCancellationRequested)
                _timer.Change((Int32)TimeSpan.FromMinutes(1).TotalMilliseconds, Timeout.Infinite);
        }

        public virtual void Dispose()
        {
            _cts.Cancel();
            _timer?.Dispose();
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("定时服务开启");
            _timer = new Timer(DoWork, _cts, (Int32)TimeSpan.FromMinutes(1).TotalMilliseconds, Timeout.Infinite);
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("定时服务关闭");
            _cts.Cancel();
            _timer.Change(Timeout.Infinite, 0);
            //_timer?.Dispose();
            return Task.CompletedTask;
        }
    }
}
